#include "ScreenHandler.h"
#include "WorldHandler.h"
#include "PlayerObject.h"
#include "Config.h"
#include "EventHandler.h"
#include "NetworkHandler.h"

ScreenHandler globalScreenHandler;

#define PLAYERSPAWN core::vector3df(500.f, 25,500.f)

ScreenHandler::ScreenHandler()
{
	isTyping = false;
	isZooming = false;
	
	chatInputBox = NULL;
	
	zoomFactor = 10.0f;
	currentZoom = 100.0f;

	selector = NULL;
	inactiveSelector = NULL;
}


void ScreenHandler::setup()
{
	video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
	device = createDevice(driverType, core::dimension2d<u32>(globalConfig.getScreenWidth(), globalConfig.getScreenHeight()), 32, globalConfig.getScreenFullscreen(), false, true, globalEventHandler.getEventReceiver());
	driver = device->getVideoDriver();
	driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
	smgr = device->getSceneManager();
	
	camera = smgr->addCameraSceneNode(0, core::vector3df(PLAYERSPAWN.X+CAMERAROTATION, PLAYERSPAWN.Y+CAMERAZOOM,PLAYERSPAWN.Z+CAMERAROTATION), PLAYERSPAWN, CAMERAID);
    camera->setFarValue(42000.0f);
	
	currentResolution = driver->getCurrentRenderTargetSize();
    
	createInputBox();
}

ScreenHandler::~ScreenHandler()
{

}

void ScreenHandler::setTerrainTriangleSelector(scene::ITriangleSelector* newSelector)
{
	selector = newSelector;
}

scene::ITriangleSelector* ScreenHandler::getTerrainTriangleSelector()
{
	return selector;
}

void ScreenHandler::swapTerrainTriangleSelectors()
{
	scene::ITriangleSelector* temp = selector;
	selector = inactiveSelector;
	inactiveSelector = temp;
}

void ScreenHandler::setCameraNode(scene::ICameraSceneNode* newCamera)
{
	camera = newCamera;
}

scene::ICameraSceneNode* ScreenHandler::getCameraNode()
{
	return camera;
}

IrrlichtDevice* ScreenHandler::getDevice()
{
	return device;
}

video::IVideoDriver* ScreenHandler::getDriver()
{
	return driver;
}

scene::ISceneManager* ScreenHandler::getSmgr()
{
	return smgr;
}

void ScreenHandler::appendToChatLog(const std::string& passedString)
{
	chatLog.append(passedString);
	
	size_t newlineCount = 0;

	for(size_t i = 0; i < chatLog.length(); ++i)
	{
		if(chatLog[i] == '\n')
		{
			++newlineCount;
		}
	}
	
	if(newlineCount > 10)
	{
		chatLog = chatLog.substr(chatLog.find('\n')+1);
	}
}

void ScreenHandler::setChatLog(const std::string& passedChatLog)
{
	chatLog = passedChatLog; 
}

const std::string& ScreenHandler::getChatLog()
{
	return chatLog;
}

void ScreenHandler::focusInputBox()
{
	device->getGUIEnvironment()->setFocus((gui::IGUIElement*)chatInputBox);
}

void ScreenHandler::createInputBox()
{
	gui::IGUIFont* font = device->getGUIEnvironment()->getFont(FONT);
	//chatInputBox = device->getGUIEnvironment()->addEditBox(L"",  core::rect<s32>(12, globalConfig.getScreenHeight()-250, 300,  globalConfig.getScreenHeight()-200), false, 0, 31337);
	chatInputBox = device->getGUIEnvironment()->addEditBox(L"",  core::rect<s32>(12,  currentResolution.Height-50, 300,  currentResolution.Height), false, 0, 31337);
	chatInputBox->setOverrideColor(video::SColor(255,255,255,0));
	chatInputBox->setOverrideFont(font);
	
	chatInputBox->setVisible(false);
	device->getGUIEnvironment()->setFocus(NULL);
}

void ScreenHandler::createStatsPane()
{
		gui::IGUISkin* skin = device->getGUIEnvironment()->getSkin();
		
}

void ScreenHandler::showInputBox()
{
	chatInputBox->setText(L"");
	chatInputBox->setVisible(true);
	device->getGUIEnvironment()->setFocus((gui::IGUIElement*)chatInputBox);
}

void ScreenHandler::hideInputBox()
{
	chatInputBox->setVisible(false);
	device->getGUIEnvironment()->setFocus(NULL);
}


bool ScreenHandler::getIsTyping()
{
	return isTyping;
}

void ScreenHandler::setIsTyping(bool passedValue)
{
	isTyping = passedValue;
}

void ScreenHandler::drawNames()
{
	gui::IGUIFont* font = device->getGUIEnvironment()->getFont(FONT);
	scene::ISceneCollisionManager* collisionmgr = smgr->getSceneCollisionManager();
	
	std::vector<LivingObject*> livingObjects = globalWorldHandler.getLivingObjects();
	
	size_t size = livingObjects.size();
	for(size_t i = 0; i < size; ++i)
	{
		LivingObject* livingObject = livingObjects[i]; 

		if(livingObject->getObjectType() != PLAYER_OBJECT
		|| (livingObject->getObjectType() == PLAYER_OBJECT && reinterpret_cast<PlayerObject*>(livingObject)->getIsConnected() == false))
		{
			continue;
		}
		//aplode}
		#if 0
		if(livingObject->getObjectType() == PLAYER_OBJECT
		&& reinterpret_cast<PlayerObject*>(livingObject)->getIsConnected() == false)
		{
			continue;
		}
		#endif 
		core::vector3df pos = livingObject->getPosition();
		
		core::stringw name = "";
		name += livingObject->getName().c_str();
		unsigned int centerOffset = name.size() * 4 - 2; // oh god how did this get here i am not good with computer
		
		core::position2d<s32> pos2d = collisionmgr->getScreenCoordinatesFrom3DPosition(core::vector3df(pos.X, pos.Y, pos.Z));
		font->draw(name, core::rect<s32>(pos2d.X-centerOffset,pos2d.Y-75, 0, 0), video::SColor(255,255,255,255));
	}
}

void ScreenHandler::drawChatLog()
{
	gui::IGUIFont* font = device->getGUIEnvironment()->getFont(FONT);
	
	core::rect<s32> chatRect(10, currentResolution.Height-200, 0, 0);
		
	core::stringw chatLogW = "";
	chatLogW += chatLog.c_str();
	
	font->draw(chatLogW, chatRect, video::SColor(255, 255, 255, 147));
}

int ScreenHandler::renderHUD(int lastFPS)
{
   	int FPS = driver->getFPS();
   	if(lastFPS != FPS)
   	{
	   	core::stringw str;
		str = L"Akuma II - [";
		str += driver->getName();
		str += "]";
   		device->setWindowCaption(str.c_str());
   	}
   	
   	gui::IGUIFont* font = device->getGUIEnvironment()->getFont(FONT);

	core::stringw versionstr;
	versionstr += L"Akuma II Alpha Build 0.2 - Öckersoft Corporation\nFPS: ";
	versionstr += FPS;
	font->draw(versionstr, 
	core::rect<s32>(10,10,10,50), video::SColor(255,255,255,255));
	
	
	if(globalConfig.getIsServer() == true
	|| globalCSHandler->getHasConnection() == true)
	{
		drawNames();
		drawStats();
		drawChatLog();
	}
	
	device->getGUIEnvironment()->drawAll();

	return FPS;
}

void ScreenHandler::setCurrentZoom(f32 passedDelta)
{
	currentZoom = zoomFactor * -passedDelta; // passedDelta is revier, riveting Irrlicht etc.
	
	isZooming = true;
}

void ScreenHandler::moveCamera()
{
	if(globalWorldHandler.getPlayerObjectsCount() > globalWorldHandler.getLocalPlayerIndex())
	{
		std::vector<PlayerObject*> playerObjects = globalWorldHandler.getPlayerObjects();

  		f32 cameraY = camera->getPosition().Y;
  		if(isZooming)
  		{
  			cameraY += currentZoom;
  			isZooming = false;
  		}

		if(cameraY <= 240 || cameraY > 400)
		{
			cameraY -= currentZoom;
		}
  		core::vector3df playerPos = playerObjects[globalWorldHandler.getLocalPlayerIndex()]->getPosition();
		
		camera->setPosition(core::vector3df(playerPos.X+CAMERAROTATION, cameraY, playerPos.Z+CAMERAROTATION));
		camera->setTarget(playerPos);
	}
}

void ScreenHandler::renderWorld()
{
	smgr->drawAll();
}

const wchar_t* ScreenHandler::getInputBoxContents()
{
	return chatInputBox->getText();
}

void ScreenHandler::highlightNode(scene::ISceneNode* node)
{
	//node->setMaterialFlag(video::EMF_LIGHTING, false);
}

void ScreenHandler::drawStats()
{
	std::vector<PlayerObject*> playerObjects = globalWorldHandler.getPlayerObjects();
	PlayerObject* playerObject = playerObjects[globalWorldHandler.getLocalPlayerIndex()];
	
	gui::IGUISkin* skin = device->getGUIEnvironment()->getSkin();
	//skin->draw3DSunkenPane(device->getGUIEnvironment()->getRootGUIElement(), video::SColor(210, 210, 210, 210), 
	
	
	core::stringw q;
	q += "HP: ";
	q += playerObject->HP;
	
	q += " \n\nKills:\n===========\n";
	size_t size = playerObjects.size();
	for(size_t i = 0; i < size; ++i)
	{
		PlayerObject* playerObject= playerObjects[i]; 
		q += playerObject->getName().c_str();
		q += ": ";
		q += playerObject->killCount;
		q += "\n";
	}
	
	gui::IGUIFont* font = device->getGUIEnvironment()->getFont(FONT);
	font->draw(q, core::rect<s32>(10, 400, 10,50), video::SColor(255,255,255,255));
}
